#pragma once
#include <netinet/in.h>
#include <string_view>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/un.h>
#include <unistd.h>

class unix_server{
    enum class mode{
        STREAM = ::SOCK_STREAM,
        DGRAM = ::SOCK_DGRAM,
        SEQPACKET = ::SOCK_SEQPACKET
    };
public:
    unix_server(std::string_view unix_path){
        m_sock = socket(PF_UNIX, SOCK_STREAM, 0);
        if (m_sock == -1){
            perror("创建socket失败\n");
            exit(-1);
        }

        memset(&m_sockaddr, 0, sizeof(m_sockaddr));
        m_sockaddr.sun_family = AF_UNIX;
        strcpy(m_sockaddr.sun_path, unix_path.data());


        if (bind(m_sock, reinterpret_cast<sockaddr*>(&m_sockaddr), sizeof(m_sockaddr)) == -1){
            perror("bind函数执行时发生错误\n");
            exit(-1);
        }

        if (listen(m_sock, 5) == -1){
            perror("listen函数执行时发生错误\n");
            exit(-1);
        }
    }

    int accept(){
        sockaddr_un client_sockaddr;
        socklen_t client_socklen = sizeof(client_sockaddr);
        int client_sock = ::accept(m_sock, reinterpret_cast<sockaddr*>(&client_sockaddr), &client_socklen);
        return client_sock;
    }

    int get_sockfd(){
        return m_sock;
    }

    void close(){
        if (m_sock != -1){
            ::close(m_sock);
            m_sock = -1;
        }
    }

    ~unix_server(){
        close();
    }
private:
    int m_sock;
    sockaddr_un m_sockaddr;
};